import 'package:bot_toast/bot_toast.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';

import 'image_utils.dart';
import 'locale_util.dart';

/// 弹出提示层,其他位置弹出提示信息时统一调用该方法;
/// 避免风格不统一, 同时避免更好方案时内容改动较大
class Toast {
  /// 显示单纯文本
  ///
  /// [message] 显示的文本内容
  ///
  /// [onlyOne] 是否单例显示
  static CancelFunc showMessage(
    String message, {
    Alignment align = Alignment.center,
    Duration duration = const Duration(seconds: 2),
    bool onlyOne = true,
  }) {
    return _customToastWidget(
      message,
      align: align,
      duration: duration,
      onlyOne: onlyOne,
    );
  }

  /// 显示成功信息提示
  ///
  /// [onlyOne] 是否单例显示
  static CancelFunc showSuccess(
    String message, {
    Alignment align = const Alignment(0, 0.8),
    Duration duration = const Duration(seconds: 2),
    bool onlyOne = true,
  }) {
    return _customToastWidget(
      message,
      icon: Icon(
        // Icons.done_rounded,
        Icons.check_circle_outline_rounded,
        color: Colors.white,
      ),
      align: align,
      duration: duration,
      onlyOne: onlyOne,
    );
  }

  /// 显示普通信息提示
  ///
  /// [onlyOne] 是否单例显示
  static CancelFunc showInfo(
    String message, {
    Alignment align = const Alignment(0, 0.8),
    Duration duration = const Duration(seconds: 2),
    bool onlyOne = true,
  }) {
    return _customToastWidget(
      message,
      icon: Icon(
        // Icons.info,
        Icons.info_outline_rounded,
        color: Colors.white,
      ),
      align: align,
      duration: duration,
      onlyOne: onlyOne,
    );
  }

  /// 显示警告信息提示
  ///
  /// [onlyOne] 是否单例显示
  static CancelFunc showWarn(
    String message, {
    Alignment align = const Alignment(0, 0.8),
    Duration duration = const Duration(seconds: 2),
    bool onlyOne = true,
  }) {
    return _customToastWidget(
      message,
      icon: Icon(
        Icons.warning_amber_rounded,
        color: Colors.white,
      ),
      align: align,
      duration: duration,
      onlyOne: onlyOne,
    );
  }

  /// 显示异常信息提示
  ///
  /// [onlyOne] 是否单例显示
  static CancelFunc showError(
    String message, {
    Alignment align = const Alignment(0, 0.8),
    Duration duration = const Duration(seconds: 2),
    bool onlyOne = true,
  }) {
    return _customToastWidget(
      message,
      icon: Icon(
        Icons.error_outline_rounded,
        color: Colors.white,
      ),
      align: align,
      duration: duration,
      onlyOne: onlyOne,
    );
  }

  /// 显示加载提示框
  ///
  /// [loadingMsg] 加载框中显示的文本
  ///
  /// [cancelToken] 用于取消api请求
  static CancelFunc showLoading({
    String? loadingMsg,
    Duration? duration,
    CancelToken? cancelToken,
  }) {
    return _lodingWidget(
      loadingMsg,
      duration: duration,
      cancelToken: cancelToken,
    );
  }

  /// 显示通知栏消息
  ///
  /// [leading] 左侧图标
  ///
  /// [closeIcon] 删除图标
  ///
  /// [duration] 显示时长
  ///
  /// [hideCloseButton] 是否隐藏删除图标, 默认不隐藏
  ///
  /// [onPressed] 通知栏点击事件
  static CancelFunc showNotification({
    Widget? leading,
    String? title,
    String? subTitle,
    Icon? closeIcon,
    Duration duration = const Duration(seconds: 5),
    bool hideCloseButton = false,
    bool onlyOne = true,
    VoidCallback? onPressed,
  }) {
    return _customNotificationWidget(
      ClipRRect(
        borderRadius: BorderRadius.all(Radius.circular(8.0)),
        child: leading ?? loadImage('canyou_logo', width: 45.0, height: 45.0),
      ),
      title ?? "通知提醒",
      subTitle,
      closeIcon: closeIcon,
      duration: duration,
      hideCloseButton: hideCloseButton,
      onlyOne: onlyOne,
      onPressed: onPressed,
    );
  }

  /// 绘制自定义提示框
  ///
  /// [text] 提示文本
  ///
  /// [icon] 图标按钮
  static CancelFunc _customToastWidget(
    String text, {
    Widget? icon,
    Alignment align = Alignment.center,
    Duration duration = const Duration(seconds: 2),
    bool onlyOne = true,
  }) {
    return BotToast.showCustomText(
      clickClose: false,
      crossPage: true,
      onlyOne: onlyOne,
      align: align,
      duration: duration,
      toastBuilder: (_) {
        return LayoutBuilder(
          builder: (BuildContext context, BoxConstraints constraints) {
            final theme = Theme.of(context);
            final borderRadius = const BorderRadius.all(Radius.circular(10.0));
            return Container(
              constraints: constraints.copyWith(
                maxWidth: constraints.biggest.width * 0.6,
                maxHeight: constraints.biggest.height * 0.6,
              ),
              padding: const EdgeInsets.symmetric(
                vertical: 15.0,
                horizontal: 20.0,
              ),
              decoration: BoxDecoration(
                color: Colors.black87,
                borderRadius: borderRadius,
                boxShadow: [
                  BoxShadow(
                    color: Colors.black26,
                    // offset: const Offset(0.0, 0.0),
                    blurRadius: 5.0,
                    spreadRadius: 0.0,
                  ),
                ],
              ),
              child: IntrinsicWidth(
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    if (icon != null)
                      Container(
                        // color: Colors.red,
                        padding: EdgeInsets.only(right: 5.0),
                        child: icon,
                      ),
                    Expanded(
                      child: Text(
                        "${text != '' ? text : '未知异常'}",
                        style: theme.textTheme.titleMedium!.copyWith(
                          color: Colors.white,
                        ),
                        maxLines: 15,
                        overflow: TextOverflow.ellipsis,
                      ),
                    ),
                  ],
                ),
              ),
            );
          },
        );
      },
    );
  }

  /// 绘制自定义通知框
  ///
  /// [icon] 图标按钮
  ///
  /// [text] 提示文本
  static CancelFunc _customNotificationWidget(
    Widget leading,
    String title,
    String? subtitle, {
    Icon? closeIcon,
    bool hideCloseButton = false,
    bool onlyOne = true,
    Duration? duration,
    VoidCallback? onPressed,
  }) {
    return BotToast.showCustomNotification(
      crossPage: true,
      onlyOne: onlyOne,
      duration: duration,
      toastBuilder: (CancelFunc cancelFunc) {
        return LayoutBuilder(
          builder: (BuildContext context, BoxConstraints constraints) {
            final theme = Theme.of(context);
            final borderRadius = const BorderRadius.all(Radius.circular(8.0));
            return GestureDetector(
              onTap: () {
                if (onPressed != null) {
                  onPressed();
                  cancelFunc.call();
                }
              },
              child: Container(
                width: constraints.biggest.width * 0.95,
                padding: const EdgeInsets.symmetric(
                  vertical: 15.0,
                  horizontal: 15.0,
                ),
                decoration: BoxDecoration(
                  color: theme.canvasColor,
                  borderRadius: borderRadius,
                  boxShadow: [
                    BoxShadow(
                      color: Colors.black26,
                      offset: const Offset(0.0, 2.0),
                      blurRadius: 10.0,
                      spreadRadius: -3.0,
                    ),
                  ],
                ),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    leading,
                    const SizedBox(width: 10.0),
                    Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          Text(
                            "$title",
                            style: theme.textTheme.titleMedium!.copyWith(
                              fontWeight: FontWeight.w500,
                            ),
                            maxLines: 1,
                            overflow: TextOverflow.ellipsis,
                          ),
                          const SizedBox(height: 3.0),
                          Text(
                            "$subtitle",
                            style: theme.textTheme.bodyLarge,
                            maxLines: 3,
                            overflow: TextOverflow.ellipsis,
                          ),
                        ],
                      ),
                    ),
                    if (!hideCloseButton)
                      Material(
                        color: Colors.transparent,
                        shape: const CircleBorder(),
                        clipBehavior: Clip.hardEdge,
                        child: IconButton(
                          splashColor: Colors.white24,
                          icon: closeIcon ?? const Icon(Icons.cancel),
                          onPressed: cancelFunc,
                        ),
                      ),
                  ],
                ),
              ),
            );
          },
        );
      },
    );
  }

  /// 绘制加载消息提示框
  ///
  ///[crossPage] 跨页面显示,如果为true,则该Toast会跨越多个Route显示,
  ///如果为false则在当前Route发生变化时,会自动关闭该Toast,例如[Navigator.push]-[Navigator.pop]
  ///
  ///[allowClick] 是否在该Toast显示时,能否正常点击触发事件
  ///
  ///[clickClose] 是否在点击屏幕触发事件时自动关闭该Toast
  ///
  ///[ignoreContentClick] 是否忽视ToastContext区域
  ///这个参数如果为true时,用户点击该ToastContext区域时,用户可以的点击事件可以正常到达到Page上
  ///换一句话说就是透明的(即便是Toast背景颜色不是透明),如果为false,则情况反之
  ///
  ///[closeFunc] 该函数参数主要目的使Toast关闭之做一些处理例如
  ///触发关闭前调用[AnimationController]来启动并等待动画后再关闭
  ///
  ///[duration] 持续时间,如果为null则不会去定时关闭,如果不为null则在到达指定时间时自动关闭
  ///
  ///[backButtonBehavior] 点击物理返回键的行为(在android上等同于物理的返回键),注意不是导航条上的返回按钮
  ///如果为[ignore]则拦截返回事件,
  ///如果为[close]则关闭该toast,并且拦截事件停止冒泡
  ///如果为null or [none]则不拦截事件
  ///
  ///[cancelToken] 用于取消网络请求(拓展内容, 如果api请求允许取消时,该值不为空,显示右上角小叉按钮)
  static CancelFunc _lodingWidget(
    String? loadingMsg, {
    bool clickClose = false,
    bool allowClick = false,
    bool ignoreContentClick = false,
    bool crossPage = true,
    Duration? duration,
    CancelToken? cancelToken,
  }) {
    return BotToast.showCustomLoading(
      clickClose: clickClose,
      allowClick: allowClick,
      ignoreContentClick: ignoreContentClick,
      crossPage: crossPage,
      duration: duration,
      backButtonBehavior: BackButtonBehavior.ignore,
      backgroundColor: Colors.black12,
      toastBuilder: (CancelFunc cancelFunc) {
        return LayoutBuilder(
          builder: (BuildContext context, BoxConstraints constraints) {
            final borderRadius = const BorderRadius.all(Radius.circular(8));
            return Stack(
              children: [
                Container(
                  padding: const EdgeInsets.all(8.0),
                  decoration: BoxDecoration(
                    color: Colors.black87,
                    borderRadius: borderRadius,
                    boxShadow: [
                      BoxShadow(
                        color: Colors.black87,
                        offset: const Offset(0.0, 2.0),
                        blurRadius: 10.0,
                        spreadRadius: -5.0,
                      ),
                    ],
                  ),
                  child: SizedBox(
                    width: 85.0,
                    height: 85.0,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        SpinKitPouringHourGlass(
                          color: Colors.white,
                          size: 35.0,
                        ),
                        const SizedBox(height: 15.0),
                        Text("${loadingMsg ?? '${i18n(context).loading}...'}",
                            style: TextStyle(color: Colors.white)),
                      ],
                    ),
                  ),
                ),
                if (cancelToken != null)
                  Positioned(
                    right: 0,
                    top: 0,
                    child: SizedBox(
                      width: 30.0,
                      height: 30.0,
                      child: GestureDetector(
                        child: const Icon(CupertinoIcons.clear_circled),
                        onTap: () {
                          cancelFunc.call();
                          cancelToken.cancel();
                        },
                      ),
                    ),
                  ),
              ],
            );
          },
        );
      },
    );
  }

  static cancelToast() {
    BotToast.closeAllLoading();
  }
}
